package org.huntaway.kindergarten.service;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.huntaway.hibernate.SessionManager;
import org.huntaway.imp.StrutsToolsImp;
import org.huntaway.kernel.NutException;
import org.huntaway.kernel.imp.TimesToolsImp;
import org.huntaway.kindergarten.common.SingletonManager;
import org.huntaway.kindergarten.manager.BaseMng;
import org.huntaway.kindergarten.po.SysUser;
import org.huntaway.kindergarten.po.base.BasePo;
import org.huntaway.kindergarten.util.GlobalCon;
import org.huntaway.kindergarten.util.PageResult;
import org.huntaway.kindergarten.util.Singleton;
import org.huntaway.struts1.preprocessor.Preprocessor;

public abstract class KindProcessor<T extends BasePo> extends Preprocessor {
	protected TimesToolsImp ttl = new TimesToolsImp();
	protected final String RES_LST = "resLst";
	protected final String ID = "uid";
	protected StrutsToolsImp currTools = Singleton.currTools;
	protected SessionManager dateManage = Singleton.dateManage;
	protected static SingletonManager sm = SingletonManager.getInstance();
	protected T item;
	protected BaseMng<T> baseMng;
	protected HttpSession session = null;
	protected SysUser uib = null;

	@SuppressWarnings("unchecked")
	public List<T> findList(Object obj) {
		return dateManage.findbyhql(getListHql(obj.getClass())).list();
	}

	protected KindProcessor() {

	}

	public abstract T getObj();

	public ActionForward list(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ActionForward serBean = super.list(mapping, form, request, response);
		item = (T) setValue(request, getObj());
		PageResult pageResult = setPageVar(request);
		baseMng.list(pageResult, item);
		request.setAttribute(RES_LST, pageResult.getResLst());
		return serBean;
	}

	private PageResult setPageVar(HttpServletRequest request) {
		return new PageResult();
	}

	public ActionForward query(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		request.setAttribute("statusCode", GlobalCon.SUCCESS_CODE);
		ActionForward serBean = super.list(mapping, form, request, response);
		item = (T) setValue(request, getObj());
		PageResult pageResult = setPageVar(request);
		baseMng.query(pageResult, item);
		request.setAttribute(RES_LST, pageResult.getResLst());
		return serBean;
	}

	public ActionForward addBegin(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		request.setAttribute("statusCode", GlobalCon.SUCCESS_CODE);
		ActionForward serBean = super
				.addBegin(mapping, form, request, response);
		return serBean;
	}

	public ActionForward addProcess(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		HttpSession session = request.getSession(true);
		uib = (SysUser) session.getAttribute("user");
		request.setAttribute("statusCode", GlobalCon.SUCCESS_CODE);
		ActionForward serBean = super.addProcess(mapping, form, request,
				response);
		item = (T) setValue(request, getObj());
		item.setAuthor(uib.getTName());
		item.setCreateDate(new Date());
		request.setAttribute("callbackType", "closeCurrent");
		baseMng.save(item);
		return serBean;
	}

	public ActionForward editBegin(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		request.setAttribute("statusCode", GlobalCon.SUCCESS_CODE);
		ActionForward serBean = super.editBegin(mapping, form, request,
				response);
		Integer keyId = currTools.toInteger(request.getParameter(ID));
		request.setAttribute("obj", dateManage.load(getObj().getClass(), keyId));
		return serBean;
	}

	public ActionForward editProcess(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		HttpSession session = request.getSession(true);
		uib = (SysUser) session.getAttribute("user");
		request.setAttribute("statusCode", GlobalCon.SUCCESS_CODE);
		ActionForward serBean = super.editProcess(mapping, form, request,
				response);
		Integer keyId = currTools.toInteger(request.getParameter(ID));
		T itemOld = (T) baseMng.load(getObj().getClass(), keyId);
		item = (T) setValue(request, itemOld);
		item.setAuthor(uib.getTName());
		item.setUpdateDate(new Date());
		baseMng.update(item);
		request.setAttribute("callbackType", "closeCurrent");
		return serBean;
	}

	public ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		request.setAttribute("statusCode", GlobalCon.SUCCESS_CODE);
		ActionForward serBean = super.delete(mapping, form, request, response);
		Integer keyId = currTools.toInteger(request.getParameter(ID));
		try {
			baseMng.delete(baseMng.getEntityById(getObj().getClass(), keyId));
		} catch (NutException e) {
			// serBean = mapping.findForward(ERR);
			request.setAttribute("statusCode", GlobalCon.ERRORR_CODE);
			request.setAttribute("Mes", e.getMessage());
		}
		return serBean;
	}

	@SuppressWarnings("unchecked")
	public T setValue(HttpServletRequest request, T item) {
		Enumeration<String> requestEnum = request.getParameterNames();
		while (requestEnum.hasMoreElements()) {
			String name = requestEnum.nextElement().toString();
			try {
				String str = "";
				if (request.getCharacterEncoding() == null) {
					str = transCode(request.getParameter(name));
				} else {
					str = request.getParameter(name);
				}
				if (str == null || str.equals("")) {
					continue;
				}
				request.setAttribute(name, str);
				Field fieldItem = getFielld(item.getClass(), name);
				if (fieldItem == null
						|| Modifier.isFinal(fieldItem.getModifiers())) {
					continue;
				}
				fieldItem.setAccessible(true);
				setValue(fieldItem, item, str);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
				continue;
			} catch (IllegalAccessException e) {
				e.printStackTrace();
				continue;
			}
		}
		return item;
	}

	protected void setValue(Field fieldItem, Object obj, String str)
			throws IllegalArgumentException, IllegalAccessException {
		if (fieldItem.getType().equals(String.class)) {
			fieldItem.set(obj, str);
			return;
		}
		if (fieldItem.getType().equals(Integer.class)) {
			fieldItem.set(obj, Integer.parseInt(str));
			return;
		}
		if (fieldItem.getType().equals(java.util.Date.class)) {
			fieldItem.set(obj, getDate(str));
			return;
		}
		if (fieldItem.getType().equals(BigDecimal.class)) {
			fieldItem.set(obj, new BigDecimal(str));
			return;
		}
		Class<?> clazzType = fieldItem.getType();
		fieldItem.set(obj, dateManage.load(clazzType, Integer.parseInt(str)));
	}

	private Date getDate(String str) {
		try {
			return ttl.str2Time(str, TimesToolsImp.STY_24);
		} catch (NutException e) {
			e.printStackTrace();
		}
		return null;
	}

	private String transCode(String value) {
		try {
			return currTools.transCode(value, "iso-8859-1", "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "";
	}
}
